local Item = import(".Item")
local Equip = import(".Equip")
local Jewel = import(".Jewel")
local DataModel = import(".DataModel")
local Bag = class("Bag",DataModel)

function Bag:ctor()
	Bag.super.ctor(self)

	self._bagLv = 0 --背包等级
	self:clear()
end

function Bag:clear()
	self.items={}
	self._bagLv = 0

	self._applyEnable = true -- 是否可以apply，把更数据更新消息延迟发送
	self._applyDict = {} --不能发送消息期间的更新数据
end

local function fetchItemType(value)
	local itemBagType
	local data
	if value.equip then
		itemBagType = Enums.ItemBagType.equip
		data = value.equip
	elseif value.item then
		itemBagType = Enums.ItemBagType.item
		data = value.item
	elseif value.jewel then
		itemBagType = Enums.ItemBagType.jewel
		data = value.jewel
	else
		print("!!!!!unknow item type")
	end
	return itemBagType,data
end

function Bag:read(value)
	self._bagLv = value.bagID or 0

	local bagcells = value.cells
	if bagcells then
		for _,value in pairs(bagcells) do
			local itemBagType,data = fetchItemType(value)
			if data then
				local item
				if itemBagType == Enums.ItemBagType.equip then
					item = Equip.new()
				elseif itemBagType == Enums.ItemBagType.jewel then
					item = Jewel.new()
				else
					item = Item.new(itemBagType)
				end
				item:read(data)
				if item:isValid() then
					self.items[item.uid]=item
				else
					release_print("Bag:read item not valid ",item.tid)
				end
			end
		end
	end
end

function Bag:write(value)
	for uid,item in pairs(self.items) do
		if item.isNew then
			table.insert(value, uid)
		end
	end
	--dump(value, "Bag.write")
end

function Bag:setBagLv( bagLv )
	self._bagLv = tonumber( bagLv ) or 0
end

function Bag:getBagLv()
	return self._bagLv
end

-- 当前背包等级是否最大等级
function Bag:isCurBagLvMax()
	local bagConfs = GD:getBagConfs()
	return self._bagLv >= #bagConfs
end

function Bag:apply(oper,dispathEvent,ignoreNew)
	local itemBagType,value = fetchItemType(oper.Bag.cells[1])

	if not value then
		return
	end

	local uid = value.uid
	local item = self.items[uid]
	local amountGot = 0
	local amountBefor = (item and item.amount or 0)
	if oper.opt=="insert" or oper.opt=="update" then
		if not item then
			if itemBagType == Enums.ItemBagType.equip then
				item=Equip.new()
			elseif itemBagType == Enums.ItemBagType.jewel then
				item=Jewel.new()
			else
				item=Item.new(itemBagType)
			end
		end
		item:read(value)
		amountGot = item.amount-amountBefor

		if amountGot>0 and not ignoreNew then
			item:setIsNewGet(true)
		end
		self.items[uid] = item
	elseif oper.opt=="delete" then
		self.items[uid] = nil
		amountGot = -amountBefor
	end

	if dispathEvent then
		if self._applyEnable then
			self:dispatchChange(uid,item,amountGot,oper.opt)
		else
			self._applyDict[uid] = {item=item, amountGot=amountGot, opt=oper.opt}
		end
	end
	return item,amountGot
end

function Bag:setApplyEnable(b)
	self._applyEnable = b
	if b then
		for k,v in pairs(self._applyDict) do
			self:dispatchChange(k, v.item, v.amountGot, v.opt)
		end

		self._applyDict = {}
	end
end

function Bag:onGotItem(listener)
	return self:onChanged(function(uid,item,amountGot,opt)
		if amountGot>0 then
			listener(uid,item,amountGot,opt)
		end
	end)
end

function Bag:getItemIsNews()
	local isNewItems = {}
	for uid,item in pairs(self.items) do
		if item.isNew then
			table.insert(isNewItems,uid)
		end
	end
	return isNewItems
end

function Bag:setItemIsNews(itemUIDs)
	for _,uid in pairs(itemUIDs) do
		local item = self.items[uid]
		if item then
			item.isNew = true
		end
	end
end

return Bag
